/* $Id: icaro_science.c,v 1.29 2009/02/10 09:16:12 llundin Exp $
 *
 * This file is part of the IIINSTRUMENT Pipeline
 * Copyright (C) 2002,2003 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: llundin $
 * $Date: 2009/02/10 09:16:12 $
 * $Revision: 1.29 $
 * $Name:  $
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/*-----------------------------------------------------------------------------
                                Includes
 -----------------------------------------------------------------------------*/

#include <algorithm>
#include <thread>
#include <iostream>
#include "RecipeFactory.h"
#include "IcaroScience.h"

/*-----------------------------------------------------------------------------
                            C Function declarations
 -----------------------------------------------------------------------------*/

extern "C"
{
	int registerRecipe();
}

/*-----------------------------------------------------------------------------
                            Static variables
 -----------------------------------------------------------------------------*/

const std::string IcaroScience::s_Name = "icaro_science";

const std::string IcaroScience::s_Synopsis =
    "This recipe makes Icaro fly";

const std::string IcaroScience::s_Description =
    "This example text is used to describe the recipe.\n"
    "The description should include the required FITS-files and\n"
    "their associated tags, e.g.\n"
    "IIINSTRUMENT-RRRECIPE-raw-file.fits " "\n"
    "and any optional files, e.g.\n"
    "IIINSTRUMENT-RRRECIPE-flat-file.fits ""\n"
    "\n"
    "Additionally, it should describe functionality of the expected output."
    "\n";

/*-----------------------------------------------------------------------------
                            Recipe implementation
 -----------------------------------------------------------------------------*/

/**
 * @brief    IcaroScience constructor 
 */

IcaroScience::IcaroScience() :
Recipe(IcaroScience::s_Version,
       IcaroScience::s_Name,
       IcaroScience::s_Synopsis,
       IcaroScience::s_Description,
       "Firstname Lastname", PACKAGE_BUGREPORT,
       "License")
{
}

/**
 * @brief    IcaroScience recipe execution
 * This is where all the processing is taking place 
 */
void IcaroScience::go_impl_()
{
	//Fill some data buffer
    std::vector<double> data;
    const int ndata = 10000;
    data.assign(ndata, 2.4);

    //Run in different threads
    std::thread t1(&IcaroScience::processDataBuffer_, this, data, 0);
    std::thread t2(&IcaroScience::processDataBuffer_, this, data, 1);
    t1.join();
    t2.join();
    //This is without threads
    //processDataBuffer_(data, 0);
    //processDataBuffer_(data, 1);

    //Output result
    info_("Result for detector 0: %g",m_sum[0]);
    info_("Result for detector 1: %g",m_sum[1]);
    
}

double IcaroScience::processDataBuffer_
(const std::vector<double>& data, int detector_id)
{
	double    sum = 0;
	int       idata;
	int       itimes;
	const int ntimes = 200000;

	for(itimes = 0; itimes<ntimes; ++itimes)
	{
		if(int(itimes * 10 / ntimes) ==  itimes / double(ntimes) * 10.)
			info_("Detector %d Doing iteration %d",
				  detector_id, itimes);
		for(auto it = data.begin(), idata=1; it != data.end(); ++it, ++idata)
			sum += *it + detector_id;
	}
	m_sum[detector_id] = sum;
	return sum;
}

/*-----------------------------------------------------------------------------
                            Function implementation
 -----------------------------------------------------------------------------*/

int registerRecipe()
{    
    Refran::RecipeFactory::instance().insertCreator<IcaroScience>
        (IcaroScience::s_Name, IcaroScience::s_Version);
    return 1;
}
